package com.gregbugaj.nscaffold.type;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.gregbugaj.nscaffold.exception.RepositoryException;

/**
 * Hold all the registered TypeRevolvers
 * @author gbugaj
 *
 */
public class TypeResolverRegistry {
	public  List<TypeResolver<?>> resolvers;
	private Map<Class<?>, TypeResolver<?>> resolverCache;

	public TypeResolverRegistry() {
		resolvers=new ArrayList<TypeResolver<?>>();
		resolverCache=new HashMap<Class<?>, TypeResolver<?>>();
		
		try {
			register(new HibernateTypeResolver());
		} catch (RepositoryException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Add new resolver
	 * @param resolver to add
	 */
	public void register(TypeResolver<?> resolver) throws RepositoryException{
		if (resolver== null)throw new RepositoryException("Resolver can't be null");
		resolvers.add(resolver);		
	}

	/**
	 * Lookup existing resolver if nothing found throw exception 
	 * @param type
	 */
	public TypeResolver<?> lookup(Class<?> type) throws RepositoryException{
		TypeResolver<?> cachedResolver=resolverCache.get(type);
		if(cachedResolver!=null){
			return cachedResolver;
		}
		for(TypeResolver<?> resolver:resolvers){
			if(resolver.canResolve(type)){
				resolverCache.put(type, resolver);
				return resolver;
			}			
		}
		throw new RepositoryException("No Resolver Available");
	}

}
